package cn.iocoder.yudao.module.eval.service.candidate;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.eval.controller.admin.candidate.vo.EvalCandidateInfoPageReqVO;
import cn.iocoder.yudao.module.eval.controller.admin.candidate.vo.EvalCandidateInfoSaveReqVO;
import cn.iocoder.yudao.module.eval.dal.dataobject.candidate.EvalCandidateInfoDO;
import cn.iocoder.yudao.module.eval.dal.mysql.candidate.EvalCandidateInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.eval.enums.ErrorCodeConstants.*;

/**
 * 参评人员信息 Service 实现类
 *
 * @author lfl
 */
@Service
@Validated
@Slf4j
public class EvalCandidateInfoServiceImpl implements EvalCandidateInfoService {

    @Resource
    private EvalCandidateInfoMapper candidateInfoMapper;

    @Override
    public Long createCandidateInfo(EvalCandidateInfoSaveReqVO createReqVO) {
        // 校验计划和身份证号的唯一性
        validateCandidateInfoUnique(null, createReqVO.getPlanId(), createReqVO.getIdNumber());

        // 插入
        EvalCandidateInfoDO candidateInfo = BeanUtils.toBean(createReqVO, EvalCandidateInfoDO.class);
        candidateInfo.setRegistrationTime(LocalDateTime.now());
        candidateInfoMapper.insert(candidateInfo);
        // 返回
        return candidateInfo.getId();
    }

    @Override
    public void updateCandidateInfo(EvalCandidateInfoSaveReqVO updateReqVO) {
        // 校验存在
        validateCandidateInfoExists(updateReqVO.getId());
        // 校验计划和身份证号的唯一性
        validateCandidateInfoUnique(updateReqVO.getId(), updateReqVO.getPlanId(), updateReqVO.getIdNumber());

        // 更新
        EvalCandidateInfoDO updateObj = BeanUtils.toBean(updateReqVO, EvalCandidateInfoDO.class);
        candidateInfoMapper.updateById(updateObj);
    }

    @Override
    public void deleteCandidateInfo(Long id) {
        // 校验存在
        validateCandidateInfoExists(id);
        // 删除
        candidateInfoMapper.deleteById(id);
    }

    private void validateCandidateInfoExists(Long id) {
        if (candidateInfoMapper.selectById(id) == null) {
            throw exception(CANDIDATE_INFO_NOT_EXISTS);
        }
    }

    private void validateCandidateInfoUnique(Long id, Long planId, String idNumber) {
        EvalCandidateInfoDO candidateInfo = candidateInfoMapper.selectByPlanIdAndIdNumber(planId, idNumber);
        if (candidateInfo == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的参评人员
        if (id == null) {
            throw exception(CANDIDATE_INFO_DUPLICATE);
        }
        if (!candidateInfo.getId().equals(id)) {
            throw exception(CANDIDATE_INFO_DUPLICATE);
        }
    }

    @Override
    public EvalCandidateInfoDO getCandidateInfo(Long id) {
        return candidateInfoMapper.selectById(id);
    }

    @Override
    public List<EvalCandidateInfoDO> getCandidateInfoList(Collection<Long> ids) {
        return candidateInfoMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<EvalCandidateInfoDO> getCandidateInfoPage(EvalCandidateInfoPageReqVO pageReqVO) {
        return candidateInfoMapper.selectPage(pageReqVO);
    }

    @Override
    public List<EvalCandidateInfoDO> getCandidateInfoListByPlanId(Long planId) {
        return candidateInfoMapper.selectListByPlanId(planId);
    }

    @Override
    public EvalCandidateInfoDO getCandidateInfoByPlanIdAndCandidateId(Long planId, Long candidateId) {
        return candidateInfoMapper.selectByPlanIdAndCandidateId(planId, candidateId);
    }

    @Override
    public EvalCandidateInfoDO getCandidateInfoByPlanIdAndIdNumber(Long planId, String idNumber) {
        return candidateInfoMapper.selectByPlanIdAndIdNumber(planId, idNumber);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchImportCandidateInfo(List<EvalCandidateInfoSaveReqVO> candidateInfoList, Long planId, String importBatchId) {
        for (EvalCandidateInfoSaveReqVO candidateInfoReqVO : candidateInfoList) {
            // 设置计划ID和导入批次ID
            candidateInfoReqVO.setPlanId(planId);
            candidateInfoReqVO.setImportBatchId(importBatchId);
            candidateInfoReqVO.setDataSource(3); // 批量导入
            
            // 检查是否已存在
            EvalCandidateInfoDO existingInfo = candidateInfoMapper.selectByPlanIdAndIdNumber(planId, candidateInfoReqVO.getIdNumber());
            if (existingInfo == null) {
                // 创建新记录
                createCandidateInfo(candidateInfoReqVO);
            } else {
                // 更新现有记录
                candidateInfoReqVO.setId(existingInfo.getId());
                updateCandidateInfo(candidateInfoReqVO);
            }
        }
    }

    @Override
    public void updateRegistrationStatus(Long id, Integer registrationStatus) {
        // 校验存在
        validateCandidateInfoExists(id);

        // 更新状态
        EvalCandidateInfoDO updateObj = new EvalCandidateInfoDO();
        updateObj.setId(id);
        updateObj.setRegistrationStatus(registrationStatus);
        if (registrationStatus == 2) { // 已确认
            updateObj.setConfirmationTime(LocalDateTime.now());
        }
        candidateInfoMapper.updateById(updateObj);
    }

    @Override
    public List<EvalCandidateInfoDO> getCandidateInfoListByImportBatchId(String importBatchId) {
        return candidateInfoMapper.selectListByImportBatchId(importBatchId);
    }

}
